package org.jeecg.modules.alarm.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhouwr.common.enums.NoticeType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.alarm.entity.AlarmConfig;
import org.jeecg.modules.alarm.entity.AlarmConfigTrigger;
import org.jeecg.modules.alarm.enums.AlarmActuatorType;
import com.zhouwr.common.enums.AlarmLevel;
import org.jeecg.modules.alarm.service.IAlarmConfigService;
import org.jeecg.modules.alarm.service.IAlarmTriggerService;
import org.jeecg.modules.alarm.vo.AlarmConfigPage;
import org.jeecg.modules.alarm.vo.AlarmConfigVo;
import org.jeecg.modules.device.entity.DeviceInstance;
import org.jeecg.modules.device.service.IDeviceInstanceService;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.server.PathParam;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 告警配置
 * @Author: jeecg-boot
 * @Date: 2021-01-11
 * @Version: V1.0
 */
@Api(tags = "告警配置")
@RestController
@RequestMapping("/alarm/config")
@Slf4j
public class AlarmConfigController {
    @Autowired
    private IAlarmConfigService alarmConfigService;
    @Autowired
    private IAlarmTriggerService alarmTriggerService;
    @Autowired
    private IDeviceInstanceService instanceService;

    @Autowired
    private ISysBaseAPI sysBaseAPI;

    /**
     * 列表查询
     *
     * @param alarmConfig
     * @param req
     * @return
     */
    @AutoLog(value = "告警配置-列表查询")
    @ApiOperation(value = "告警配置-列表查询", notes = "告警配置-列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryList(AlarmConfig alarmConfig, HttpServletRequest req) {
        QueryWrapper<AlarmConfig> queryWrapper = QueryGenerator.initQueryWrapper(alarmConfig, req.getParameterMap()).orderByAsc("instance_id");
        List<AlarmConfigVo> list = alarmConfigService.list(queryWrapper).stream().map(config -> {
            AlarmConfigVo configVo = new AlarmConfigVo(config);
            DeviceInstance instance = instanceService.getById(config.getInstanceId());
            if (instance != null) {
                configVo.setInstanceName(instance.getName());
            }
            return configVo;
        }).collect(Collectors.toList());
        return Result.ok(list);
    }

    /**
     * 分页列表查询
     *
     * @param alarmConfig
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "告警配置-分页列表查询")
    @ApiOperation(value = "告警配置-分页列表查询", notes = "告警配置-分页列表查询")
    @GetMapping(value = "/pageList")
    public Result<?> queryPageList(AlarmConfig alarmConfig,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<AlarmConfig> queryWrapper = QueryGenerator.initQueryWrapper(alarmConfig, req.getParameterMap());
        Page<AlarmConfig> page = new Page<AlarmConfig>(pageNo, pageSize);
        IPage<AlarmConfig> pageList = alarmConfigService.page(page, queryWrapper);
        return Result.ok(pageList);
    }

    @ApiOperation(value = "告警配置-获取执行类型")
    @GetMapping(value = "/getActuatorType")
    public Result<?> getActuatorType() {
        return Result.ok(AlarmActuatorType.toJSONArray());
    }

    @ApiOperation(value = "告警配置-获取消息配置")
    @GetMapping(value = "/getNoticeConfig")
    public Result<?> getNoticeConfig() {
        return Result.ok(sysBaseAPI.queryMsgConfig());
    }

    /**
     * 获取消息类型
     *
     * @return
     */
    @ApiOperation(value = "告警配置-消息类型")
    @GetMapping(value = "/getNoticeType")
    public Result<?> getNoticeType() {
        return Result.ok(NoticeType.toJSONArray());
    }

    /**
     * 查询系统消息模板
     *
     * @param tempType 系统-4、短信-1、邮件-2、微信-3
     * @return
     */
    @GetMapping(value = "/querySysMsgTemplate/{tempType}")
    public Result<?> querySysMsgTemplate(@PathParam(value = "tempType") String tempType) {
        return Result.ok(sysBaseAPI.queryMsgTemplate(tempType));
    }

    /**
     * @return
     */
    @GetMapping(value = "/getAlarmLevel")
    public Result<?> getAlarmLevel() {
        return Result.ok(AlarmLevel.toJSONArray());
    }

    /**
     * 添加
     *
     * @param alarmConfigVo
     * @return
     */
    @AutoLog(value = "告警配置-添加")
    @ApiOperation(value = "告警配置-添加", notes = "告警配置-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody AlarmConfigVo alarmConfigVo) {
        alarmConfigService.saveMain(alarmConfigVo);
        return Result.ok("添加成功！");
    }

    /**
     * 编辑
     *
     * @param alarmConfigVo
     * @return
     */
    @AutoLog(value = "告警配置-编辑")
    @ApiOperation(value = "告警配置-编辑", notes = "告警配置-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody AlarmConfigVo alarmConfigVo) {
        alarmConfigService.updateMain(alarmConfigVo);
        return Result.ok("编辑成功!");
    }

    /**
     * 修改状态
     *
     * @param id
     * @param state
     * @return
     */
    @AutoLog(value = "告警配置-修改状态")
    @ApiOperation(value = "告警配置-修改状态", notes = "告警配置-修改状态")
    @GetMapping(value = "/setState/{id}/{state}")
    public Result<?> setState(@PathVariable String id, @PathVariable Integer state) {
        boolean update = alarmConfigService.lambdaUpdate().eq(AlarmConfig::getId, id).set(AlarmConfig::getState, state).update();
        return update ? Result.ok("修改状态成功") : Result.error("修改状态失败");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "告警配置-通过id删除")
    @ApiOperation(value = "告警配置-通过id删除", notes = "告警配置-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        alarmConfigService.delMain(id);
        return Result.ok("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "告警配置-批量删除")
    @ApiOperation(value = "告警配置-批量删除", notes = "告警配置-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.alarmConfigService.delBatchMain(Arrays.asList(ids.split(",")));
        return Result.ok("批量删除成功！");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "告警配置-通过id查询")
    @ApiOperation(value = "告警配置-通过id查询", notes = "告警配置-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        AlarmConfig alarmConfig = alarmConfigService.getById(id);
        if (alarmConfig == null) {
            return Result.error("未找到对应数据");
        }
        return Result.ok(alarmConfig);
    }

    @AutoLog(value = "告警配置-通过instanceId查询")
    @ApiOperation(value = "告警配置-通过instanceId查询", notes = "告警配置-通过instanceId查询")
    @GetMapping(value = "/queryByInstanceId/{instanceId}")
    public Result<?> queryByInstanceId(@PathVariable String instanceId) {
        List<AlarmConfig> alarmConfigs = alarmConfigService.lambdaQuery().eq(AlarmConfig::getInstanceId, instanceId).list();
        return Result.ok(alarmConfigs);
    }

    @AutoLog(value = "告警配置-通过实例instanceId所在分组查询")
    @ApiOperation(value = "告警配置-通过instanceId查询", notes = "告警配置-通过instanceId查询")
    @GetMapping(value = "/querySameLevelByInstanceId/{instanceId}")
    public Result<?> querySameLevelByInstanceId(@PathVariable String instanceId) {
        List<DeviceInstance> instanceList = instanceService.querySameLevelById(instanceId).stream()
                .filter(instance -> this.alarmConfigService.lambdaQuery().eq(AlarmConfig::getInstanceId, instance.getId()).count() > 0)
                .collect(Collectors.toList());
        return Result.ok(instanceList);
    }

    @AutoLog(value = "告警配置-根据id查询整体")
    @ApiOperation(value = "告警配置-根据id查询整体", notes = "告警配置-根据id查询整体")
    @GetMapping(value = "/queryWholeById")
    public Result<?> queryWholeById(@RequestParam(name = "id", required = true) String id) {
        AlarmConfigVo alarmConfigVo = alarmConfigService.buildAlarmConfigVoById(id);
        if (alarmConfigVo == null) {
            return Result.error("未找到对应数据");
        }
        return Result.ok(alarmConfigVo);
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "告警触发器-通过主表ID查询")
    @ApiOperation(value = "告警触发器-通过主表ID查询", notes = "告警触发器-通过主表ID查询")
    @GetMapping(value = "/queryAlarmTriggerByMainId")
    public Result<?> queryAlarmTriggerListByMainId(@RequestParam(name = "id", required = true) String id) {
        List<AlarmConfigTrigger> alarmConfigTriggerList = alarmTriggerService.selectByMainId(id);
        IPage<AlarmConfigTrigger> page = new Page<>();
        page.setRecords(alarmConfigTriggerList);
        page.setTotal(alarmConfigTriggerList.size());
        return Result.ok(page);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param alarmConfig
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, AlarmConfig alarmConfig) {
        // Step.1 组装查询条件查询数据
        QueryWrapper<AlarmConfig> queryWrapper = QueryGenerator.initQueryWrapper(alarmConfig, request.getParameterMap());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        //Step.2 获取导出数据
        List<AlarmConfig> queryList = alarmConfigService.list(queryWrapper);
        // 过滤选中数据
        String selections = request.getParameter("selections");
        List<AlarmConfig> alarmConfigList = new ArrayList<AlarmConfig>();
        if (oConvertUtils.isEmpty(selections)) {
            alarmConfigList = queryList;
        } else {
            List<String> selectionList = Arrays.asList(selections.split(","));
            alarmConfigList = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
        }

        // Step.3 组装pageList
        List<AlarmConfigPage> pageList = new ArrayList<AlarmConfigPage>();
        for (AlarmConfig main : alarmConfigList) {
            AlarmConfigPage vo = new AlarmConfigPage();
            BeanUtils.copyProperties(main, vo);
            List<AlarmConfigTrigger> alarmConfigTriggerList = alarmTriggerService.selectByMainId(main.getId());
            vo.setAlarmConfigTriggerList(alarmConfigTriggerList);
            pageList.add(vo);
        }

        // Step.4 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, "告警配置列表");
        mv.addObject(NormalExcelConstants.CLASS, AlarmConfigPage.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("告警配置数据", "导出人:" + sysUser.getRealname(), "告警配置"));
        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
        return mv;
    }
}